package br.com.iswe.gwt.ui.client.base;

import java.util.List;
import java.util.Map;

import br.com.iswe.gwt.manter.client.BaseService;
import br.com.iswe.gwt.ui.client.MessagePanel;
import br.com.iswe.gwt.util.client.ClientUtils;
import br.com.iswe.gwt.util.client.QueryInfo;
import br.com.iswe.gwt.util.client.QueryListener;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.Widget;

public abstract class BaseConsultarPanel extends Composite {
	//Painel Base
	protected FlexTable base = new FlexTable();
	//Paineis de Filtro e Lista
	protected BaseListaPanel listaPanel;
	protected BaseFiltroPanel filtroPanel;

	//Service Handler
	protected BaseService service = BaseService.getService();

	
	//Message Handler
	protected MessagePanel messagePanel = MessagePanel.getInstance();
	
	public BaseConsultarPanel(){
		initWidget(base);
		initLayOut();
	}
	
	public BaseConsultarPanel(ClickListener detalharListener){
		this.detalharListener = detalharListener;
		initWidget(base);
		initLayOut();
	}
	
	public BaseConsultarPanel(MessagePanel messagePanel, ClickListener detalharListener){
		//TODO: Remover do construtor MessagePanel
		this.detalharListener = detalharListener;
		initWidget(base);
		initLayOut();
	}
	
	protected void initLayOut(){
		//Painel de Filtro
		base.setWidget(0, 0, getFiltroPanel());
		//painel de resultado da pesquisa.
		base.getFlexCellFormatter().setVerticalAlignment(1, 0, HasVerticalAlignment.ALIGN_TOP);
		base.getFlexCellFormatter().setHeight(1, 0, "100%");
		base.setWidget(1, 0, getListaPanel());
	}
	
	public void refresh(){
		listaPanel.reset();
	}
	
	//Metodos abstratos
	public abstract BaseListaPanel getListaPanel();
	public abstract BaseFiltroPanel getFiltroPanel();
	
	public abstract String[] getPropriedadesConsulta();
	
	////////////////////////////////////////////////////////////
	////// Handlers //////
	////////////////////////////////////////////////////////////
	//Metodo que carrega os dados do servidor para a tabela
	protected QueryListener queryListener = null;
	protected QueryListener getQueryListener(){
		if(queryListener == null){
			queryListener =  new QueryListener() {
				public void executeImpl(QueryInfo queryInfo){
					//Muda o estado do painel de filtro para em espera.
					getFiltroPanel().notificarEmEspera();
					listaPanel.notificarEmEspera();
					MessagePanel.getInstance().showWaitMessage(true);
					
					//obtem o filtro para passar para o servico de pesquisa
					Map bean = getParameters();
					//especifica os campos que seram necessarios
					//nas informacoes da consulta.
					queryInfo.setListaPropriedades(getPropriedadesConsulta());
					//executa a consulta.
					getService().consultar(bean, queryInfo, getResultCallBack());
				}
			};
		}
		return queryListener;
	}
	
	/**
	 * Retorna um mapa com os parametros da pesquisa.
	 * 
	 * @return
	 */
	protected Map getParameters(){		
		//obtem o filtro para passar para o servico de pesquisa
		return getFiltroPanel().getForm().getMapValues();
	}
	
	protected AsyncCallback resultCallBack = null;
	protected AsyncCallback getResultCallBack(){
		if(resultCallBack == null){
			resultCallBack = new AsyncCallback(){
				//Popula os resultados.
				public void onSuccess(Object result) {
					//Muda o estado do painel de filtro para concluido.
					getFiltroPanel().notificarConcluido();
					listaPanel.notificarConcluido();
					//esconde o pop-up de Aguarde...
					MessagePanel.getInstance().hideWaitMessage();
					//Popular com os dados recebidos.
					List dados = (List)result;
					getListaPanel().populate(dados);
				}
				public void onFailure(Throwable caught) {
					//Muda o estado do painel de filtro para concluido.
					getFiltroPanel().notificarConcluido();
					listaPanel.notificarConcluido();
					MessagePanel.getInstance().hideWaitMessage();
					MessagePanel.getInstance().showError(caught, ClientUtils.commonConstants.erroConsulta());
				}
			};
		}
		return resultCallBack;
	}
	protected final ClickListener pesquisaClickListener = new ClickListener() {
		public void onClick(Widget sender) {
			consultar();
		}
	};
	
	//Evento de teclado para ativar a pesquisa
	protected final KeyboardListener pesquisaKeyboardListener = new KeyboardListenerAdapter() {
		public void onKeyPress(Widget sender, char keyCode, int modifiers) {
			if(keyCode == KEY_ENTER){
				consultar();
			}	
		}
	};
	
	public void consultar(){
		if(filtroPanel.validate()){
			//Carre a lista de Pesquisa na tabela
			getQueryListener().execute(listaPanel.newQueryInfo());
		}
	}
	
	protected ClickListener detalharListener = null;

	public ClickListener getDetalharListener() {
		return detalharListener;
	}
}
